﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RussiaLibrary
{
    public enum Polygon_Stament{
         INIT,
         USED,//USED
         NO_USED,//NO_CHANGE
         MAX
    };//创建一个枚举来表示当前方块是否可变形

    enum Polygon_Control{
         UP,
         DOWN,
         RIGHT,
         LEFT
    }//创建一个枚举来表示方块的移动方向。

    enum Polygon_Chang { 
         Y_CHANG,
         N_CHANG,
    }
    public class Class_Polygon//所有方块的基类
    {
        protected List<KeyValuePair<int,int>> points = new List<KeyValuePair<int,int>>();//创建一个集合保存当前的方块形状；

        public virtual bool Init(byte[,] Bytes_TetrisByte) { return true; }//虚拟的初始化方法，可以根据不同的形状进行不同的初始化；

        protected int State = -2;//定义一个变量记录当前方块的状态,(int)Polygon_Stament.MAX

        public virtual void Change(byte[,] Bytes_TetrisByte) { return; }//虚拟变形方法；

        private bool CheckContinue(byte[,] Bytes_TetrisByte,Polygon_Control dir)
        {
            switch (dir)
            {
                case Polygon_Control.DOWN:
                    foreach (KeyValuePair<int, int> point in points)
                    {
                        if (point.Key + 1 > Class_Common.Length - 1 || Bytes_TetrisByte[point.Key + 1, point.Value] == 2)//(int)Polygon_Stament.NO_USED
                        {
                            return false;
                        }//当已经到底，或者下一个点已经被占用，那么就不能再继续下降了
                    }
                    break;
                case Polygon_Control.UP://变形
                    break;
                case Polygon_Control.RIGHT:
                    foreach (KeyValuePair<int, int> point in points)
                    {
                        if (point.Value + 1 > Class_Common.Width - 1 || Bytes_TetrisByte[point.Key, point.Value + 1] == 2)//(int)Polygon_Stament.NO_USED
                        {
                            return false;
                        }
                    }
                    break;
                case Polygon_Control.LEFT:
                    foreach (KeyValuePair<int, int> point in points)
                    {
                        if (point.Value - 1 < 0 || Bytes_TetrisByte[point.Key, point.Value - 1] == 2)//(int)Polygon_Stament.NO_USED
                        {
                            return false;
                        }
                    }
                    break;
            }
            return true;
        }
        public bool MoveDown(byte[,] Bytes_TetrisByte)
        {
            if (CheckContinue(Bytes_TetrisByte, Polygon_Control.DOWN))
            {
                RealMoveDown(Bytes_TetrisByte);
                return true;
            }
            else {
                Fasten(Bytes_TetrisByte);
                return false;
            }        
        }
        private bool RealMoveDown(byte[,] Bytes_TetrisByte)
        {
            List<KeyValuePair<int, int>> newPoints = new List<KeyValuePair<int, int>>();
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key, point.Value] = 0;//(int)Polygon_Stament.INIT
            }//该循环是清空正在下落原有的方块，并非真正的清空，只是让其不在显示。
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key + 1, point.Value] = (int)Polygon_Stament.USED;
                newPoints.Add(new KeyValuePair<int, int>(point.Key + 1, point.Value));
            }//该循环是刷新方块位置。
            points = newPoints;
            return true;
        }
        private void Fasten(byte[,] Bytes_TetrisByte)
        {
            foreach(KeyValuePair<int,int> point in points)
            {
                Bytes_TetrisByte[point.Key,point.Value] = 2;
            }
            Clear(Bytes_TetrisByte);
            return;
        }
        private void Clear(byte[,] Bytes_TetrisByte)
        {
            for(int i = 0;i < Class_Common.Length;i++)
            {
                bool needclear = true;
                for (int j = 0; j < Class_Common.Width;j++)
                {
                    if (Bytes_TetrisByte[i, j] != 2)
                    {
                        needclear = false;
                        break;
                    }
                }
                if (needclear)
                {
                    for (int k = 0; k < Class_Common.Width; k++)//消除方块
                    {
                        Bytes_TetrisByte[i, k] = 0;
                    }
                    //消除后需要将上面的方块往下降
                    int row = i;
                    for (int k = row; k > 0; k--)//从第i行开始，之前的每行逐行下降；
                    {
                        if (k - 1 > 0)//K最多等于1，等于1后，第0行已经进行了。
                        {
                            for (int m = 0; m < Class_Common.Width; m++)
                            {
                                if (Bytes_TetrisByte[k, m] == 0)//如果当前列的状态为0，那么则将前一行到方块下落到当前行。
                                {
                                    Bytes_TetrisByte[k, m] = Bytes_TetrisByte[k - 1, m];
                                }
                            }
                        }
                    }
                }
            }
        }
        public bool RealMoveLeft(byte[,] Bytes_TetrisByte)
        {
            if (!CheckContinue(Bytes_TetrisByte, Polygon_Control.LEFT))
            {
                return false;
            }

            List<KeyValuePair<int, int>> newPoints = new List<KeyValuePair<int, int>>();
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key, point.Value] = 0;//(int)Polygon_Stament.INIT
            }//该循环是清空正在下落原有的方块，并非真正的清空，只是让其不在显示。
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key, point.Value - 1] = 1;//(int)Polygon_Stament.USED
                newPoints.Add(new KeyValuePair<int, int>(point.Key, point.Value - 1));
            }//该循环是刷新方块位置。
            points = newPoints;
            return true;
        }

        public bool RealMoveRight(byte[,] Bytes_TetrisByte)
        {
            if (!CheckContinue(Bytes_TetrisByte, Polygon_Control.RIGHT))
            {
                return false;
            }

            List<KeyValuePair<int, int>> newPoints = new List<KeyValuePair<int, int>>();
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key, point.Value] = 0;//(int)Polygon_Stament.INIT
            }//该循环是清空正在下落原有的方块，并非真正的清空，只是让其不在显示。
            foreach (KeyValuePair<int, int> point in points)
            {
                Bytes_TetrisByte[point.Key, point.Value + 1] = 1;//(int)Polygon_Stament.USED
                newPoints.Add(new KeyValuePair<int, int>(point.Key, point.Value + 1));
            }//该循环是刷新方块位置。
            points = newPoints;
            return true;
        }

        public bool MoveUp(byte[,] Bytes_TetrisByte)
        {
            //暂时空缺
            return true;
        }

        protected bool InitBase(byte[,] Bytes_TetrisByte, params KeyValuePair<int, int>[] initpoints)
        {
            foreach(KeyValuePair<int,int> point in initpoints)
            {
                if (Bytes_TetrisByte[point.Key, point.Value] == 2)
                {
                    return false;
                }
                Bytes_TetrisByte[point.Key, point.Value] = 1;//(int)Polygon_Stament.INIT
                points.Add(point);
            }
            return true;
        }
    }
}
